package main

import "fmt"

/*
闭包:指引用了外部函数作用域中的变量的函数。也即，闭包是一个函数及其相关引用环境的组合。
匿名函数和闭包的关系:匿名函数可以用来创建闭包,当一个匿名函数引用了外部函数作用域中的变量时,该匿名函数就成了一个闭包。
*/

//需求，有个函数每次调用之后的返回值都是增加一次之后的值

// 1、普通函数做法(需要先声明全局变量)，不足：被迫定义全局变量，并且累加之后不能改变值
var count int // 首先声明全局变量
func autoadd() int {
	count += 1
	return count
}

// 2、采用闭包和匿名函数做法
func autoadd2() func() int {
	local := 0
	return func() int {
		local += 1 //实现了一个函数中调用另外一个函数的局部变量，实现闭包
		return local
	} //注意这里便是返回一个函数，要是后面再接()表示返回调用后的值
}

func main() {
	for i := 0; i < 10; i++ {
		fmt.Println(autoadd())
	}

	// 调用自加函数，这样解决全局定义变量的问题
	nextFunc := autoadd2() //在这里执行一次获得local的初始化，并获得返回函数
	//执行自加
	for i := 0; i < 10; i++ {
		fmt.Println(nextFunc())
	}

	//假如想local重新归为0，再次累加，只需要再调用就可以
	nextFunc2 := autoadd2()
	for i := 0; i < 5; i++ {
		fmt.Println(nextFunc2())
	}

}
